
#include <sys/stat.h>
#include "file_list_view.h"

enum {
	COLUMN_FILE_NAME,
	COLUMN_FILE_SIZE,
	N_COLUMNS
};

static gpointer
fill_file_list (gpointer data)
{
	FileListView* 		flv;
	GtkTreeIter			iter;
	GError*				error = NULL;
	GFile*				dir = NULL;
	GFileEnumerator*	enumerator = NULL;

	flv = (FileListView*) data;
	
	/*assert(flv->list_view);
	assert(flv->list_store);
	assert(flv->path);*/
	
	/*g_print ("fill_file_list: %s\n", flv->path);*/
	
	dir = g_file_new_for_path (flv->path);
	enumerator = g_file_enumerate_children (dir, "standard::*,owner::user", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error);
	if(enumerator)
	{
		GFileInfo*	info;

		while ((info = g_file_enumerator_next_file (enumerator, NULL, NULL)) != NULL)
		{
			GFileType 	file_type;
			gchar* 		file_display_name = NULL;
			goffset		file_size; // gint64

			file_type = g_file_info_get_file_type (info);
			file_size = g_file_info_get_size (info);

			if (file_type == G_FILE_TYPE_DIRECTORY)
			{
				file_display_name = g_strdup_printf ("[%s]", g_file_info_get_display_name (info));
			}
			else
			{
				file_display_name = g_strdup_printf ("%s", g_file_info_get_display_name (info));
			}

			gtk_list_store_append (flv->list_store, &iter);
			gtk_list_store_set (flv->list_store, &iter, 
					COLUMN_FILE_NAME, file_display_name,
					COLUMN_FILE_SIZE, file_size,
					-1);

			// Cleanup
			g_object_unref (info);
			
			if (file_display_name)
			{
				g_free (file_display_name);
			}
		}
	}
	
	if(dir)
	{
		g_object_unref (dir);
	}
	
	if(enumerator)
	{
		g_object_unref (enumerator);
	}

	if(error)
	{
		g_error_free(error);
	}

	g_free (flv);
	
	return NULL;
}

static gpointer
fill_file_list2 (gpointer data)
{
	FileListView* 		flv;
	GtkTreeIter		iter;
	GDir*			dir = NULL;
	const gchar*		filename;
	GError*			error = NULL;

	flv = (FileListView*) data;
	
	/*assert(flv->list_view);
	assert(flv->list_store);
	assert(flv->path);*/
	
	g_print ("fill_file_list: %s\n", flv->path);

	dir = g_dir_open (flv->path, 0, &error);
	if(!dir)
	{
		g_print ("Error	fill_file_list2 g_dir_open: %s\n", error->message);
		g_error_free(error);
		g_free (flv);
		return NULL;
	}

	while ((filename = g_dir_read_name (dir)) != NULL)
	{
		struct stat st;
		gchar* file_display_name = NULL;
		gchar* file_path = g_build_filename (flv->path, filename, NULL);

		/*g_print ("%s\n", filename);*/

		if(g_lstat (file_path, &st) == 0)
		{
			if (st.st_mode & S_IFDIR)
			{
				file_display_name = g_strdup_printf ("[%s]", filename);
			}
			else
			{
				file_display_name = g_strdup_printf ("%s", filename);
			}

			gtk_list_store_append (flv->list_store, &iter);
			gtk_list_store_set (flv->list_store, &iter, 
					COLUMN_FILE_NAME, file_display_name,
					COLUMN_FILE_SIZE, st.st_size,
					-1);

			if (file_display_name)
			{
				g_free (file_display_name);
			}
		}
		else
		{
			g_print ("Failed to stat file %s\n", file_path);
		}
		
		g_free (file_path);
	}
	
	if(dir)
	{
		g_dir_close (dir);
	}
	
	if(error)
	{
		g_error_free(error);
	}

	g_free (flv);
	
	return NULL;
}

GtkWidget* 
file_list_view_new (const gchar* path)
{
	GtkWidget*			list_view;
	GtkCellRenderer*	renderer;
	GtkTreeViewColumn*	column;
	GtkListStore*		list_store;
	
	list_store = gtk_list_store_new (
			N_COLUMNS,
			G_TYPE_STRING,
			G_TYPE_ULONG);	

	list_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL(list_store));
	g_object_unref (G_OBJECT(list_store));

	/* The 'Name' column */
	column = gtk_tree_view_column_new ();
	gtk_tree_view_column_set_title (column, "Name");
	gtk_tree_view_column_set_resizable (column, TRUE);
	gtk_tree_view_column_set_sort_column_id (column, COLUMN_FILE_NAME);
	gtk_tree_view_column_set_sort_indicator (column, TRUE);

	renderer = gtk_cell_renderer_text_new ();
	g_object_set (G_OBJECT(renderer), 
			"width", 250,
			"ellipsize", PANGO_ELLIPSIZE_END,
			"ellipsize-set", TRUE,
			NULL);
	gtk_tree_view_column_pack_start (column, renderer, FALSE);
	gtk_tree_view_column_set_attributes (
			column, 
			renderer, 
			"text", COLUMN_FILE_NAME, 
			NULL);
	gtk_tree_view_append_column (GTK_TREE_VIEW(list_view), column);
	
	/* The 'Size' column */
	column = gtk_tree_view_column_new ();
	gtk_tree_view_column_set_title (column, "Size");
	gtk_tree_view_column_set_resizable (column, TRUE);

	renderer = gtk_cell_renderer_text_new();
	g_object_set (G_OBJECT(renderer),
			"width", 100,
			"ellipsize", PANGO_ELLIPSIZE_END,
			"ellipsize-set", TRUE,
			NULL);
	gtk_tree_view_column_pack_start (column, renderer, FALSE);
	gtk_tree_view_column_set_attributes (
			column, 
			renderer,
			"text", COLUMN_FILE_SIZE,
			NULL);
	gtk_tree_view_append_column (GTK_TREE_VIEW(list_view), column);

	/* Fill the list view with file data asynchronously */
	FileListView* flv = g_new (FileListView, 1);
	flv->list_view = list_view;
	flv->list_store = list_store;
	flv->path = path;
	if(!g_thread_create (&fill_file_list2, flv, FALSE, NULL))
	{
		g_print ("Fatal error: thread creation failed!\n");
		/*exit (-1);*/
	}

	return list_view;
}
